home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / mach / amiga / newsim.lha / takeover.asm < prev   
Encoding:
Assembly Source File  |  1993-03-21  |  14.3 KB  |  476 lines

  1. * Mach Operating System
  2. * Copyright (c) 1991,1990,1989 Carnegie Mellon University
  3. * All Rights Reserved.
  4. *
  5. * Permission to use, copy, modify and distribute this software and its
  6. * documentation is hereby granted, provided that both the copyright
  7. * notice and this permission notice appear in all copies of the
  8. * software, derivative works or modified versions, and any portions
  9. * thereof, and that both notices appear in supporting documentation.
  10. *
  11. * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  12. * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  13. * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  14. *
  15. * Carnegie Mellon requests users of this software to return to
  16. *
  17. *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
  18. *  School of Computer Science
  19. *  Carnegie Mellon University
  20. *  Pittsburgh PA 15213-3890
  21. *
  22. * any improvements or extensions that they make and grant Carnegie Mellon
  23. * the rights to redistribute these changes.
  24.  
  25. * Code to load Mach from AmigaDOS, take over the machine, set up a
  26. * temporary virtual memory state until Mach's pmap module can get itself
  27. * together, and run it by way of SIM.
  28. *
  29. * Author: Bryan Ford
  30.  
  31. * Currently this is the one module that requires a commercial program to
  32. * build.  I can't find a free assembler that understands Motorola syntax
  33. * (gas doesn't) _and_ supports the MMU instructions (A68k doesn't).
  34. * I've included this module already assembled in 'takeover.bin', but
  35. * this isn't really a solution.
  36.  
  37. * Source completely adapted to A68K v2.71 by S. Walter
  38. * The MMU instructions are still realized as 'DC.W's, later there will
  39. * hopefully be macros. 
  40.  
  41.  
  42.  
  43. *********************************************************************
  44.  
  45. *** Library offsets for exec.library
  46.  
  47. FUNC_CNT     SET    -30
  48.  
  49. FUNCDEF         MACRO
  50. _LVO\1         EQU    FUNC_CNT
  51. FUNC_CNT     SET    FUNC_CNT-6    * Standard offset-6 bytes each
  52.          ENDM
  53.  
  54.         include "ai:exec/exec_lib.i"
  55.  
  56.  
  57.  
  58. *** Some symbols directly extracted from include/exec/
  59. *** If neccessary include include files instead
  60.  
  61. MemList        equ    322
  62.  
  63. LH_HEAD        equ    0
  64. LH_TAIL        equ    4
  65. LH_TAILPRED    equ    8
  66. LH_TYPE        equ    12
  67. LH_pad        equ    13
  68.  
  69. MH_ATTRIBUTES    equ    14
  70. MH_FIRST    equ    16
  71. MH_LOWER    equ    20
  72. MH_UPPER    equ    24
  73. MH_FREE        equ    28
  74. MH_SIZE        equ    32
  75.  
  76. MEMB_PUBLIC    equ    0
  77. MEMF_PUBLIC    equ    1
  78. MEMB_CHIP    equ    1
  79. MEMF_CHIP    equ    2
  80. MEMB_FAST    equ    2
  81. MEMF_FAST    equ    4
  82.  
  83.  
  84.  
  85. *** Bryan's macros
  86.  
  87. bz      macro   ; <label>               ; Branch if zero
  88.         beq.\0  \1
  89.         endm
  90.  
  91. bnz     macro   ; <label>               ; Branch if zero
  92.         bne.\0  \1
  93.         endm
  94.  
  95.  
  96.  
  97. *** Instructions A68k simply does not understand
  98.  
  99. bhs    macro
  100.     bcc.\0  \1
  101.     endm
  102.  
  103.  
  104.  
  105. *** SIM symbol node 
  106.  
  107. sym_next    equ    0    ;+0    Next node in chain
  108. sym_number    equ    4    ;+4    Number of symbols in this node
  109. sym_length    equ    8    ;+8    Length from sym_next to free space
  110. sym_size    equ    12    ;+12    Size of node
  111. sym_highest    equ    16    ;+16    Highest value in node
  112. sym_lowest    equ    20    ;+20    Lowest value in node
  113. sym_free    equ    24    ;+24    Free space in node
  114. sym_key        equ    28    ;+28    Key for node
  115. sym_first    equ    32    ;+32    First symbol
  116.  
  117. sym_value    equ    0    ;+0    Value
  118. sym_offset    equ    4    ;+4    Offset to next value
  119. sym_namelen    equ    6    ;+6    Number of bytes of name
  120. sym_name    equ    7    ;+7    Name
  121.  
  122.  
  123.  
  124. *** Some nice stuff really needed
  125.  
  126. MIN_PMEM                equ     (1*1024*1024)   ; Minimum physical memory we can reasonably run in
  127.  
  128. VM_MIN_KERNEL_ADDRESS   equ     $40000000       ; Virtual address of kernel (and SIM)
  129.  
  130. ROMSIZE                 equ     $00ffffec       ; Absolute location of ROM size longword
  131. ROMEND                  equ     $01000000       ; Absolute location of end of ROM
  132.  
  133.  
  134.  
  135. *********************************************************************
  136.  
  137. *** entry - Entrypoint from mach.asm
  138.  
  139. entry
  140.         move.l  a0,d6                           ; Kernel load image address
  141.  
  142.         lea     entry(pc),a4
  143.  
  144.         move.l  4,a6
  145.  
  146.         jsr     _LVODisable(a6)
  147.  
  148.         moveq   #0,d2                           ; Find the largest chunk of fast memory (addr: a2, size: d2)
  149.         moveq   #0,d3                           ; ...and the size of chip memory (d3)
  150.         move.l  MemList+LH_HEAD(a6),a0          ; Assume all memory starts and stops on 64K boundaries
  151. \findmem
  152.         tst.l   (a0)
  153.         bz.b    \mem_out
  154.         move.w  MH_ATTRIBUTES(a0),d0
  155.  
  156.         btst    #MEMB_FAST,d0
  157.         bz.b    \notfast
  158.         move.l  MH_LOWER(a0),d1
  159.         clr.w   d1
  160.         move.l  d1,a1
  161.         sub.l   MH_UPPER(a0),d1
  162.         clr.w   d1
  163.         neg.l   d1
  164.         cmp.l   d2,d1
  165.         bls.b   \notfast
  166.         move.l  d1,d2
  167.         move.l  a1,a2
  168.         bra.b   \notchip
  169. \notfast
  170.         btst    #MEMB_CHIP,d0                   ; There may be multiple chip blocks because of programs
  171.         bz.b    \notchip                        ; like ChipMunch.  We assume that chip memory is "really"
  172.         move.l  MH_UPPER(a0),d1                 ; continuous and starts at 0.
  173.         neg.l   d1
  174.         clr.w   d1
  175.         neg.l   d1
  176.         cmp.l   d3,d1
  177.         bls.b   \notchip
  178.         move.l  d1,d3
  179. \notchip
  180.         move.l  (a0),a0
  181.         bra.b   \findmem
  182. \mem_out
  183.         tst.l   d3                              ; Make sure we found what we were looking for
  184.         bz.b    \config_error
  185.         cmp.l   #MIN_PMEM,d2
  186.         bhs.b   \takeover
  187. \config_error
  188.         jsr     _LVOEnable(a6)
  189.         moveq   #20,d0
  190.         rts
  191.  
  192. \takeover
  193.         jsr     _LVOSuperState(a6)
  194.         move.w  #$2700,sr
  195.         moveq   #0,d0
  196.         dc.w    $4e7b,$0002            ;<*** movec   d0,cacr
  197.         lea     stack_top(pc),sp
  198.  
  199.         move.w  #$7fff,$dff096                  ; Turn off all DMA
  200.  
  201.         lea     ROMEND,a1                       ; Sniff out the physical location of the Kickstart ROM
  202.         move.l  ROMSIZE,d0
  203.         sub.l   d0,a1                           ; (assumptions: MMU enabled, short page descriptors,
  204.  
  205.     dc.w    $f011,$9f15            ;<*** ptestr  #5,(a1),#7,a0
  206.                         ; page tables in unmapped memory)
  207.  
  208.         move.l  (a0),d1
  209.         clr.b   d1
  210.         move.l  d1,rom_pstart-entry(a4)
  211.         add.l   d0,d1
  212.         move.l  d1,rom_pend-entry(a4)
  213.  
  214.         move.l  d6,a0                           ; Beginning of hunk sizes in hunk_header
  215.         lea     20(a0),a0
  216.  
  217.         move.l  #VM_MIN_KERNEL_ADDRESS,d7       ; Kernel VM relocation offset (d7)
  218.         sub.l   a2,d7
  219.  
  220.         move.l  a2,code_addr-entry(a4)          ; Kernel code address
  221.         move.l  (a0)+,d0
  222.     lsl.l    #2,d0
  223.     move.l    a2,a3
  224.     add.l    d0,a3       
  225.  
  226.         move.l  a3,data_addr-entry(a4)          ; Kernel data address
  227.         move.l  (a0)+,d0
  228.     lsl.l    #2,d0
  229.          add.l    d0,a3
  230.  
  231.         move.l  a3,bss_addr-entry(a4)           ; Kernel bss address
  232.         move.l  (a0)+,d0                        ; Clear it
  233. \clrbss
  234.         clr.l   (a3)+
  235.         subq.l  #1,d0
  236.         bhi.b   \clrbss
  237.  
  238.         move.l  a3,sim_addr-entry(a4)           ; SIM program address
  239.         lea     sim(pc),a1                      ; Copy it
  240.         move.w  #(sim_end-sim)/4-1,d0
  241. \copysim
  242.         move.l  (a1)+,(a3)+
  243.         dbra    d0,\copysim
  244.  
  245.         move.l  a3,sym_addr-entry(a4)           ; SIM symbol node address (a3)
  246.         clr.l   (a3)+                           ; sym_next
  247.         clr.l   (a3)+                           ; sym_number
  248.         move.l  #sym_first,(a3)+                ; sym_length
  249.         clr.l   (a3)+                           ; sym_size
  250.         move.l  kern_end_addr(pc),(a3)          ; sym_highest
  251.         add.l   d7,(a3)+
  252.         move.l  #VM_MIN_KERNEL_ADDRESS,(a3)+    ; sym_lowest
  253.         clr.l   (a3)+                           ; sym_free
  254.         clr.l   (a3)+                           ; sym_key
  255.  
  256.         move.l  code_addr(pc),a1                ; Code hunk
  257.         bsr     copy_hunk
  258.         move.l  code_addr(pc),a1
  259.         bsr     reloc_hunk
  260.         move.l  code_addr(pc),a1
  261.         bsr     maybe_symbol_hunk
  262.         addq    #4,a0
  263.  
  264.         move.l  data_addr(pc),a1                ; Data hunk
  265.         bsr     copy_hunk
  266.         move.l  data_addr(pc),a1
  267.         bsr     reloc_hunk
  268.         move.l  data_addr(pc),a1
  269.         bsr     maybe_symbol_hunk
  270.         addq    #4,a0
  271.  
  272.         addq    #8,a0                           ; BSS hunk
  273.         move.l  bss_addr(pc),a1
  274.         bsr     maybe_symbol_hunk
  275.  
  276.         move.l  sim_addr(pc),a0                 ; Setup the debug server data in SIMbase
  277.         pea     16(a0)
  278.         add.l   d7,(sp)
  279.         lea     128(a0),a1
  280.         move.l  #112,(a1)+                      ; Structure size
  281.         move.l  #'MACH',(a1)+
  282.         move.l  d2,(a1)+                        ; d0 = public memory size
  283.         move.l  d3,(a1)+                        ; d1 = chip memory size
  284.         clr.l   (a1)+                           ; d2
  285.         clr.l   (a1)+                           ; d3
  286.         clr.l   (a1)+                           ; d4
  287.         clr.l   (a1)+                           ; d5
  288.         clr.l   (a1)+                           ; d6
  289.         clr.l   (a1)+                           ; d7
  290.         move.l  a2,(a1)+                        ; a0 = public memory (& kernel) physical address
  291.         move.l  a3,(a1)+                        ; a1 = physical end of kernel, first free address
  292.         move.l  rom_pstart(pc),(a1)+            ; a2 = physical start of Kickstart ROM
  293.         move.l  rom_pend(pc),(a1)+              ; a3 = physical end of Kickstart ROM
  294.         clr.l   (a1)+                           ; a4
  295.         clr.l   (a1)+                           ; a5
  296.         clr.l   (a1)+                           ; a6
  297.         clr.l   (a1)+                           ; usp
  298.         move.l  sp,(a1)+                        ; ssp
  299.         move.l  #VM_MIN_KERNEL_ADDRESS,(a1)+    ; pc
  300.         move.w  #$2700,(a1)+                    ; sr
  301.         move.l  sim_addr(pc),(a1)               ; reentry routine = reset
  302.         add.l   #sim_resethack-sim,(a1)
  303.         add.l   d7,(a1)+
  304.         clr.l   (a1)+                           ; reentry usp
  305.         clr.l   (a1)+                           ; reentry ssp
  306.         move.w  #$2700,(a1)+                    ; reentry sr
  307.         clr.l   (a1)+                           ; textstructure
  308.         clr.l   (a1)+                           ; task
  309.         clr.l   (a1)+                           ; segmentlist
  310.         move.l  sym_addr(pc),a2
  311.         move.l  a2,(a1)+                        ; d_symbol
  312.  
  313.         sub.l   a2,a3                           ; Now that all symbols are processed, finish up the node
  314.         move.l  a3,sym_length(a2)
  315.         move.l  a3,sym_size(a2)
  316.  
  317.         clr.l   -(sp)                           ; Turn off all translation
  318.     dc.w    $f017,$4000            ;<*** pmove.l (sp),tc
  319.         dc.w    $f017,$0800            ;<*** pmove.l (sp),tt0
  320.     dc.w    $f017,$0c00            ;<*** pmove.l (sp),tt1
  321.  
  322.         moveq   #0,d0                           ; Make sure the VBR is right for SIM
  323.         dc.w    $4e7b,$0801            ;<*** movec   d0,vbr
  324.  
  325.         sub.l   a0,a0
  326.         move.l  #$4E714EF9,(a0)+                ; Help Exec along during a reboot
  327.         lea     ROMEND+2,a1
  328.         sub.l   ROMSIZE,a1
  329.         move.l  a1,(a0)+
  330.         move.l  d7,a1                           ; Point all the vectors to SIM
  331.         add.l   sim_addr(pc),a1
  332.         add.l   #sim_traphack-sim,a1
  333.         move.w  #$100-2-1,d0
  334. \simize
  335.         move.l  a1,(a0)+
  336.         dbra    d0,\simize
  337.  
  338.         move.l  #$000f810f,(sp)                 ; Transparently translate up to $0fffffff
  339.         dc.w    $f017,$0800            ;<*** pmove.l (sp),tt0
  340.         neg.l   d7                              ; Translate the kernel code to its virtual address
  341.         move.l  d7,(sp)
  342.         move.l  #$80000001,-(sp)
  343.     dc.w    $f017,$4800            ;<*** pmove.q (sp),srp
  344.         move.l  #$82808880,(sp)                 ; Doesn't really matter what our geometry is...
  345.     dc.w    $f017,$4000            ;<*** pmove.l (sp),tc
  346.         addq    #8,sp
  347.  
  348.         rts                                     ; Drop into SIM's debug server (in virtual memory)
  349.  
  350. *** copy_hunk - Copy code/data hunk to its final resting place
  351. * a0 = Code/data hunk
  352. * a1 = Destination memory
  353. copy_hunk
  354.         addq    #4,a0                           ; Skip hunk type
  355.         move.l  (a0)+,d0
  356. \copy_hunk
  357.         move.l  (a0)+,(a1)+
  358.         subq.l  #1,d0
  359.         bhi.b   \copy_hunk
  360.         rts
  361.  
  362. *** reloc_hunk - Process a reloc32 hunk
  363. * a0 = Reloc32 hunk
  364. * a1 = Hunk data to relocate
  365. reloc_hunk
  366.         movem.l d6/a3/a6,-(sp)
  367.         lea     hunk_addrs(pc),a6
  368.         addq    #4,a0                           ; Skip hunk type
  369. \more
  370.         move.l  (a0)+,d0                        ; Number of relocs
  371.         bz.b    \out
  372.         move.l  (a0)+,d1                        ; Hunk to relocate to
  373.     lsl.l    #2,d1
  374.     move.l    a6,a3
  375.     add.l    d1,a3
  376.         move.l  (a3),d6
  377.         add.l   d7,d6                           ; Relocate to virtual memory, not physical
  378. \go
  379.     move.l    a1,a3
  380.     add.l    (a0)+,a3
  381.         add.l   d6,(a3)
  382.         subq.l  #1,d0
  383.         bhi.b   \go
  384.         bra.b   \more
  385. \out
  386.         movem.l (sp)+,d6/a3/a6
  387.         rts
  388.  
  389. *** maybe_symbol_hunk - Process a symbol hunk, but only if it exists (do nothing otherwise)
  390. * a0 = Next hunk, possibly a symbol hunk
  391. * a1 = Symbol offset for this symbol hunk
  392. * a3 = Current symbol pointer
  393. maybe_symbol_hunk
  394.         movem.l d7/a4-a6,-(sp)
  395.         move.l  sym_addr(pc),a6
  396.         lea     sym_number(a6),a6
  397.         add.l   d7,a1                           ; Convert physical symbol offset to virtual offset
  398.  
  399.         cmp.l   #$3f0,(a0)
  400.         bne.b   \out
  401.         addq    #4,a0
  402. \more
  403.         move.l  (a0)+,d0
  404.         bz.b    \out
  405.         add.l   d0,d0
  406.         add.l   d0,d0
  407.         move.l  a0,a4
  408.         move.l  a3,a5
  409.     add.l    d0,a0
  410.         move.l  (a0)+,d0
  411.         add.l   a1,d0
  412.         move.l  d0,(a3)+
  413.         addq    #3,a3
  414.         moveq   #-1,d0
  415. \name
  416.         addq    #1,d0
  417.         move.b  (a4)+,(a3)+
  418.         bnz.b   \name
  419.         move.b  d0,sym_namelen(a5)
  420.         addq    #sym_name+1-sym_offset,d0
  421.         move.w  d0,sym_offset(a5)
  422.  
  423.         addq.l  #1,(a6)
  424.         bra.b   \more
  425. \out
  426.         movem.l (sp)+,d7/a4-a6
  427.         rts
  428.  
  429.  
  430. *** data
  431.  
  432. stack           ds.b    8192
  433. stack_top
  434.  
  435. hunk_addrs
  436. code_addr       ds.l    1
  437. data_addr       ds.l    1
  438. bss_addr        ds.l    1
  439. kern_end_addr
  440. sim_addr        ds.l    1
  441. sym_addr        ds.l    1
  442.  
  443. rom_pstart      ds.l    1                       ; Physical location of Kickstart ROM
  444. rom_pend        ds.l    1
  445.  
  446.  
  447.  
  448. *** sim - SIM program image
  449.  
  450.         cnop    0,4
  451. sim     incbin  "mk:amiga/SIM"
  452.  
  453. sim_traphack
  454.         move.w  6(sp),-(sp)
  455.         andi.w  #$fff,(sp)
  456.         lsr.w   (sp)
  457.         lsr.w   (sp)
  458.         clr.w   -(sp)
  459.     pea    sim_sign(pc)
  460.     add.l    #sim+12-sim_sign,(sp)
  461.     rts
  462.  
  463. sim_sign
  464.         dc.l    'OKAY'
  465. sim_resethack
  466.         lea     \ttdata(pc),a0
  467.         dc.w    $f010,$0800            ;<*** pmove.l (a0),tt0
  468.         jmp     (2)
  469.  
  470. \ttdata dc.l    $000f810f
  471.  
  472.                cnop    0,4
  473. sim_end
  474.  
  475.         end
  476.